
#include <stdlib.h>
#include <stdio.h>
#include "xml.h"
#include "DataManage.h"
#include "xmlmanage.h"

//功能：从图片中取出XML尾部信息
//参数：pic					[in]输入图片
//		picLen				[in]图片大小
//		outxml				[out]尾部XML信息
//		outLen				[out]尾部信息长度
//		inLen				[in]传入的outxml总长度，用来将outxml指向空间清0信息
//返回值: 1 - 成功, 0 - 失败
int Xml_GetTailFromPic(char *pic, int picLen, char *outxml, int *outLen, int inlen)
{
	int count = picLen-1;

	memset(outxml, 0, inlen);
	if(count < 0)
		return 0;

	//找<?xml version="1.0" encoding="gb2312" ?>
	while(pic[count] != '\0')
	{
		if(pic[count] != '<')
		{
			count--;
			continue;
		}

		if(pic[count+1] != '?')
		{
			count--;
			continue;
		}

		strncpy(outxml, (pic + count), picLen - count);
		*outLen = strlen(outxml);
		return 1;
	}

	return 0;
}

//功能：异或和校验
//参数：checkpos	[in]输入数据地址
//		checklen	[in]数据长度
//		check		[out]校验值
//返回值: 1 - 成功, 0 - 失败
static int8 Xor8bitCheck(uint8 *checkpos, int32 checklen, uint8 *check)
{
	uint32 i, proglen;
	uint8 *pProg;
	uint8 xorval;
	
	pProg = checkpos;
	proglen = checklen;
	
	xorval = 0;
	for(i = 0; i < proglen; i ++)
	{
		xorval ^= *(pProg + i);
	}
	*check = xorval;
		
	return 1;
}


///////////////////////////////////////////////////////////////////////////
//主函数部分
//////////////////////////////////////////////////////////////////////////
//说明：生成调试信息参数数据(不带有头结构的XML数据)
//参数：pParam		 	[in]	调试信息参数结构
//		string			[out]	用于存放调试信息数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为图像参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeDebugParamString(SUDPDebug *pParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}

	if(Xml_MakeDebugParamXml(root, pParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;

	return 1;
}

//说明：生成侧装卡口参数数据(不带有头结构的XML数据)
//参数：pParam		 	[in]	侧装卡口参数结构
//		string			[out]	用于存放图像参数数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为图像参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeSideParamString(s_side_param *pParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}

	if(Xml_MakeSideParamXml(root, pParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;

	return 1;
}

//说明：生成图像参数数据(不带有头结构的XML数据)
//参数：pImageParam 	[in]	图像参数结构
//		string			[out]	用于存放图像参数数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为图像参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeImageParamString(SImageParam *pImageParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeImageParamXml(root, pImageParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;

	return 1;
}


//说明：生成抓拍分辨率数据(不带有头结构的XML数据)
//参数：width		 	[in]	抓拍宽
//		height			[in]	抓拍高
//		string			[out]	用于存放图像参数数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为图像参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeCapString(int32 width, int32 height, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeCapXml(root, width, height) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}

//说明：依据给定的节点数据构建XML字符串(不带有头结构的XML数据) 其路径都在
//xml/SystemConfig/SystemParam下
//参数：node			[in]	要构建的节点数据
//		string			[out]	用于存放系统配置参数数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为系统配置参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeSysCfgStr(XMLNode *node, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeSysCfgXml(root, node) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;

}
//说明：生成系统配置参数数据(不带有头结构的XML数据)
//参数：pSystemParam 	[in]	系统配置参数结构
//		string			[out]	用于存放系统配置参数数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为系统配置参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeSystemConfigString(SSystemParam *pSystemParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeSystemConfigXml(root, pSystemParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}
//说明：生成识别参数数据(不带有头结构的XML数据)
//参数：pRecParam	 	[in]	识别参数结构
//		string			[out]	用于存放识别参数数据的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为识别参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeRecParamString(SRecParam *pRecParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//printf("-------xml 0\n");
		return 0;
	}
	
	if(Xml_MakeRecParamXml(root, pRecParam) == 0)
	{
		//printf("-------xml 1\n");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//printf("-------xml 2\n");
		return 0;
	}

	*stringlen = length;
	return 1;
}

//说明：生成XML尾部信息数据(不带有头结构的XML数据)
//参数：pTailParam	 	[in]	尾部信息结构,这个参数不能为NULL
//		pPicParam		[in]	图像调光参数,这个参数为NULL时XML中将不包含这个信息
//		pRecParam		[in]	识别参数,这个参数为NULL时XML中将不包含这个信息
//		pImageParam		[in]	图像参数,这个参数为NULL时XML中将不包含这个信息
//		SSystemParam	[in]	系统参数,这个参数为NULL时XML中将不包含这个信息
//		pTailParam_VM		[in] 视频流模式下的尾部信息
//		string			[out]	用于存放尾部信息的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为识别参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeTailInfoString(STailInfo *pTailParam, SCurPicParam *pPicParam, SRecParam *pRecParam,  SImageParam *pImageParam, SSystemParam *pSystemParam, STailInfo_VideoMode *pTailParam_VM, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeTailInfoXml(root, pTailParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	if(pPicParam != NULL)
	{
		if(Xml_MakeCurPicParamXml(root, pPicParam) == 0)
		{
			//("写配置文件失败！");
			return 0;
		}
	}

	if(pRecParam != NULL)
	{
		if(Xml_MakeRecParamXml(root, pRecParam) == 0)
		{
			//("写配置文件失败！");
			return 0;
		}
	}

	if(pImageParam != NULL)
	{
		if(Xml_MakeImageParamXml(root, pImageParam) == 0)
		{
			//("写配置文件失败！");
			return 0;
		}
	}

	if(pSystemParam != NULL)
	{
		if(Xml_MakeSystemConfigXml(root, pSystemParam) == 0)
		{
			//("写配置文件失败！");
			return 0;
		}
	}

	if(pTailParam_VM != NULL)
	{
		if(Xml_MakeTailInfoXml_VideoMode(root, pTailParam_VM) == 0)
		{
			//("写配置文件失败！");
			return 0;
		}
	}

	length = Xml_MakeXmlString(string, *stringlen);

	if(length <= 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}


//说明：生成XML尾部信息数据(不带有头结构的XML数据)
//参数：pSpeedParam	 	[in]	测速信息结构,这个参数不能为NULL
//		string			[out]	用于存放尾部信息的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为识别参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeSpeedInfoString(SSpeedInfo *pSpeedParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}

	if(Xml_MakeSpeedInfoXml(root, pSpeedParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);
	if(length <= 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}

//说明：生成当前图片参数的XML数据(不带有头结构的XML数据)
//参数：pParam	 		[in]	当前图片参数信息结构
//		string			[out]	用于存放尾部信息的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为识别参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeCurPicParamString(SCurPicParam *pParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeCurPicParamXml(root, pParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}


//说明：生成XML格式的TFTP被动下载尾部信息数据(不带有头结构的XML数据)
//参数：STFTPTailInfo 	[in]	TFTP尾部信息结构
//		string			[out]	用于存放尾部信息的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为识别参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeTFTPTailInfoString(STFTPTailInfo *pTailParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeTFTPTailInfoXml(root, pTailParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}

//说明：生成XML格式的相机状态信息数据(不带有头结构的XML数据)
//参数：pStateParam 	[in]	相机状态结构
//		string			[out]	用于存放尾部信息的内存地址
//		stringlen		[in/out]输入时为内存地址大小, 输出时为识别参数数据实际大小
//返回：成功返回1，失败返回0
int32 Xml_MakeCammerStateString(SCammerState *pStateParam, int8 *string, int32 *stringlen)
{
	S_XMLItem	*root;
	int32		length = 0;

	memset(string, 0, *stringlen);

	//1 生成xml数据

	root = Xml_MakeRoot("xml");
	if(root == NULL)
	{
		//("写配置文件失败！");
		return 0;
	}
	
	if(Xml_MakeCammerStateInfoXml(root, pStateParam) == 0)
	{
		//("写配置文件失败！");
		return 0;
	}
	length = Xml_MakeXmlString(string, *stringlen);

	if(length < 0)
	{
		//("写配置文件失败！");
		return 0;
	}

	*stringlen = length;
	return 1;
}





//说明：生成用于通讯的数据(带有头结构[32字节],尾部校验[1字节]的数据)
//参数：SingString		[in]	头标识
//		inString		[in]	原始数据的内存地址
//		inLen			[in]	原始数据的长度
//		outString		[out]	用于存放加头尾后数据的首地址
//		outLen			[in/out]入是outString缓冲区的最大长度，出是加头尾后数据的长度
//返回：成功返回1，失败返回0
int32 Xml_MakeMessage(int8 SignString[32], uint8 *inString, int32 inLen, uint8 *outString, int32 *outLen)
{
//	int32		length = 0;
	uint8		check;

	memset(outString, 0, *outLen);

	if(inLen + 32 + 1 > *outLen)
	{
		//输出用的内存分配的太小
		return 0;
	}

	//1 构建头结构
	strcpy((char *)outString, SignString);
	*((uint32*)(&outString[12])) = (uint32)inLen;

	//2 添加数据
	memcpy(&outString[32], inString, inLen);


	//3 增加校验数据
	if(Xor8bitCheck(outString, inLen + 32, &check) != 1)
	{
		//生成校验码失败
		return 0;
	}

	*((uint8*)(&outString[32+inLen])) = (uint8)check;

	*outLen = inLen + 32 + 1;

	return 1;
}

//说明：生成用于通讯的数据(带型方峁筟32字节],尾部校验[1字节]的数据)
//参数：SingString		[in]	头标识
//		String			[in/out]入是不带头数据和校验的原始数据 出是加上头数据和校验的数据
//		len			[in/out]原始数据的长度
//		bufLen			[in]	入是原始数据的长度
//返回：成功返回1，失败返回0
int32 Xml_MakeMessage1(int8 SignString[32], uint8 *String, int32 *len,int32 bufLen)
{

	uint8		check;
	int32  inLen = *len;


	if(inLen + 32 + 1 > bufLen)
	{
		//输出用的内存分配的太小
		return 0;
	}

	//1 构建头结构
	strncpy((char *)String, SignString,32);
	*((uint32*)(&String[12])) = (uint32)inLen;

	//2 增加校验数据
	if(Xor8bitCheck(String, inLen + 32, &check) != 1)
	{
		//生成校验码失败
		return 0;
	}

	*((uint8*)(&String[32+inLen])) = (uint8)check;

	*len = inLen + 32 + 1;

	return 1;
}

//说明：对接收到的数据(带有头结构[32字节],尾部校验[1字节]的数据)进行校验,并去掉头结构和尾部校验
//参数：inString			[in]	收到数据的内存地址
//		inLen			[in]	收到数据的长度
//		outString		[out]	用于存放去头尾后数据的首地址
//		outLen			[in/out]入是outString缓冲区的最大长度，出是去头尾后数据的长度
//返回：成功返回1，失败返回0
int32 Xml_JieXiMessage(int8 *inString, uint32 inLen, int8 *outString, uint32 *outLen)
{
	uint32	DataLength;				//数据长度
	uint8	check;
	//以此标志开始的文件没有数据,头部正确即认为解析成功
	if(strcmp(inString,MSG_GETCAPPIC)==0)
		return 1;

	if(inLen - 32 - 1 > *outLen)
	{
		//输出用的内存分配的太小
		printf("1\n");
		return 0;
	}

	//1 解析头结构
	DataLength = *((uint32*)(&inString[12]));

	if(DataLength + 32 + 1 != inLen)		
	{
		//参数结构中表示的长度不匹配
		printf("2\n");
		return 0;
	}

	//2 校验数据是否正确
	if(Xor8bitCheck((uint8 *)inString, DataLength + 32, &check) != 1)
	{
		//生成校验码失败
		printf("3\n");
		return 0;
	}

	if(*((uint8*)(&inString[DataLength+32])) != check)			
	{
		//校验码不正确
		printf("4\n");
		return 0;
	}

	//3 取得去头尾后的数据
	memcpy(outString, &inString[32], DataLength);

	*outLen = DataLength;

	return 1;
}

















